<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Controllers - Fuel Documentation</title>
	<link href="../../assets/css/main.css" media="screen" rel="stylesheet" />
	<script type="text/javascript" src="../../assets/js/jquery-1.4.4.min.js"></script>
	<script type="text/javascript" src="../../assets/js/nav.js"></script>
	<script type="text/javascript" src="../../assets/js/highlight.pack.js"></script>
	<script type="text/javascript">
		$(function() {
			show_nav('general', '../../');
		});
		hljs.tabReplace = '    ';
		hljs.initHighlightingOnLoad();
	</script>
</head>
<body>

	<header>
		<h1>Fuel Documentation</h1>
	</header>

	<div id="main-nav"></div>

	<section id="content">
		<h2>Controllers</h2>

		<h3>What is a controller?</h3>

		<p>Controllers are classes that can be reached through the URL and take care of handling the request. A controller calls models and other classes to fetch the information and finally will pass everything to a view for output. If a URL like www.yoursite.com/example/index is requested, the first segment will be which controller is called ("example") and the second which method of that controller is called ("index").</p>

		<h3>Creating a controller</h3>

		<p>In Fuel Controllers are put in the <kbd>fuel/app/classes/controller</kbd> directory. They should (but don't have to) extend the <kbd>Controller</kbd> class and are prefixed by default by "Controller_". Below is an example of the controller "example": </p>

<pre class="php"><code>class Controller_Example extends Controller {

	public function action_index()
	{
		$data['css'] = Asset::css(array('reset.css','960.css','main.css'));
		$this->output = View::factory('test/index', $data);
	}
}</code></pre>

		<p>Methods that can be requested through the URL are prefixed with <kbd>"action_"</kbd>, this means that you're not limited by PHP's constructs on which name you might use (example: method "list" isn't allowed, "action_list" is no problem). But this also means you can give your controller public methods that can be used from other classes but are not routable.</p>

		<h4 id="more_parameters">Using more parameters from the URL</h4>

		<p>Let say we also have the following method in our Controller_Example: </p>

<pre class="php"><code>public function action_name_to_upper($name, $name_2)
{
	$data['name'] = strtoupper($name);
	$data['name_2'] = strtoupper($name_2);
	$this->output = View::factory('test/name_to_upper', $data);
}</code></pre>

		<p>If we call this method using <kdb>www.yoursite.com/example/name_to_upper/fuel/php</kbd> it will return the view <kbd>test/name_to_upper</kbd> with it given "Fuel" and "PHP" as values <var>$name_1</var> and <var>$name_2</var>. </p>

		<h4>Controller in a subdirectory</h4>

		<p>You can also put a controller in a subdirectory like <kbd>fuel/app/classes/controller/dir/test.php</kbd> in such a case the controller must include the dirname in the classname like this <var>Controller_Dir_Test</var>. </p>

		<p class="note"><strong>Please Note:</strong> Only 1 level of subdirectories is supported.</p>

		<h3>Special controller methods</h3>

		<article>
			<h4>action_index()</h4>
			<p>This method will be called if the controller is called without a second parameter. In the above example <kbd>www.yoursite.com/example/index</kbd> will be the same as <kbd>www.yoursite.com/example</kbd>.</p>
		</article>

		<article>
			<h4>before()</h4>
			<p>This method will be executed <strong>before</strong> the method from the URL is called on your controller, even if that method turns out not to exist.</p>
		</article>

		<article>
			<h4>after()</h4>
			<p>This method will be executed <strong>after</strong> the method from the URL was called successfully, this will not be called if the method turns out not to exist.</p>
		</article>

		<article>
			<h4>router($method, $params)</h4>
			<p>This method will take over the internal routing of the controller. Once the controller is loaded the router() method will be called and given the <var>$method</var> that would have been called without the router() method and the <var>$params</var> in an array that would have been given to that method. before() and after() will work as expected.</p>
		</article>

		<h3>Special controller properties</h3>

		<article>
			<h4>$request</h4>
			<p>This property holds the Request object and may not be overwritten, it can be used though to get information about the current request.</p>
		</article>

		<article>
			<h4>$output</h4>
			<p>This property holds the output that will be given to the browser, if you want to output anything don't echo it just add it to the $this->output property.</p>
		</article>

		<h3>Extending other controllers</h3>

		<p>Thanks to the autoloader you can extend other controllers without writing anything more than its name in the class definition:

<pre class="php"><code>class Controller_Example extends Controller_Welcome {

	// your methods

}</code></pre>
		
		<p>This may sound strange at first, but extending controllers allows you to share methods and create base controllers really easily.</p>

		<h3>Creating Base Controllers</h3>

		<p>
			A base controller is a shared controller, like <kbd>Controller_Public</kbd> or <kbd>Controller_Admin</kbd> and are used to share logic between groups of controllers.
			For example, the <kbd>Controller_Admin</kbd> controller could contain your login/logout actions and maybe a dashboard, but it could also contain a <kbd>before()</kbd> method
			that checks to see if the user is logged in as an admin. Then all other controllers in your admin panel will extend this an automatically be secured.
		</p>

<pre class="php"><code>class Controller_Admin extends Controller {

	public function before()
	{
		// check for admin
	}

	// your methods

	public function action_index()
	{
		// load the dashboard
	}

	public function action_login()
	{
		// log in the user
	}
}</code></pre>

		<p>That code will go in <kbd>fuel/app/classes/controller/admin.php</kbd> and all of your other controllers should go in <kbd>fuel/app/classes/controller/admin/users.php</kbd>:</p>

<pre class="php"><code>class Controller_Admin_User extends Controller_Admin {

	public function action_index()
	{
		// overrides the dashboard with the user index listing
	}

	public function action_edit($id)
	{
		// edit users
	}
}</code></pre>

	</section>

	<section id="footer">
		<p>
			<a href="http://fuelphp.com">Fuel</a> is released under the MIT license.<br />
			&copy; 2010 - 2011 Fuel Development Team
		</p>
	</section>

</body>
</html>